from app.database.postgre import SessionDep, col
from app.database.models import Account, App, Version
from app.models import responses
from app.models.common import VersionIdJSON, VersionIdParams, AppIdJSON
from app.models.versions import (AppVersionListParams, CreateAppVersionJSON, UpdateAppVersionJSON,
                                 PublishAppVersionJSON, EnforceAppVersionJSON, BatchDeleteAppVersionsJSON)


async def get_app_versions_list(
        account: Account,
        query_params: AppVersionListParams,
        session: SessionDep
):
    """获取筛选后的版本列表"""
    # 构建查询参数
    app_id = query_params.app_id
    page = query_params.page
    page_size = query_params.page_size
    version_code = query_params.version_code
    description = query_params.description
    is_publish = query_params.is_publish
    is_enforce = query_params.is_enforce
    file_md5 = query_params.file_md5
    download_url = query_params.download_url

    # 获取查询的应用
    app = session.get(App, query_params.app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 创建筛选条件
    query = session.query(Version).filter(Version.app_id == app_id).order_by(col(Version.id).asc())

    if version_code:
        query = query.filter(col(Version.version_code).like(f"%{version_code}%"))

    if is_publish is not None:
        query = query.filter(Version.is_publish == is_publish)

    if is_enforce is not None:
        query = query.filter(Version.is_enforce == is_enforce)

    if description:
        query = query.filter(col(Version.description).like(f"%{description}%"))

    if file_md5:
        query = query.filter(col(Version.file_md5).like(f"%{file_md5}%"))

    if download_url:
        query = query.filter(col(Version.download_url).like(f"%{download_url}%"))

    # 获取筛选后的总数
    total_count = query.count()
    total_pages = (total_count + page_size - 1) // page_size

    # 对筛选后的数据进行分页
    offset = (page - 1) * page_size
    paginated_query = query.offset(offset).limit(page_size)
    paginated_versions = paginated_query.all()

    return responses.SuccessResponse(
        data={
            'total': total_count,
            'total_pages': total_pages,
            'page': page,
            'page_size': len(paginated_versions),
            'list': [version.model_dump() for version in paginated_versions]
        }
    )


async def get_app_version_info(account: Account, query_params: VersionIdParams, session: SessionDep):
    """获取指定软件版本信息"""
    # 获取对应的应用
    app_id = query_params.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    # 查询对应的版本
    version = session.get(Version, query_params.version_id)
    if not version or version.app_id != app_id:
        return responses.Response803()

    return responses.SuccessResponse(data=version.model_dump())


async def create_new_app_version(account: Account, json_data: CreateAppVersionJSON, session: SessionDep):
    """创建新的版本"""
    # 获取对应的应用
    app_id = json_data.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    # 构建创建版本的参数
    version_data = json_data.model_dump()

    # 检查是否存在同名版本
    has_same_code = session.query(Version).filter(
        Version.app_id == app_id,
        Version.version_code == json_data.version_code
    ).first()
    if has_same_code:
        return responses.Response802()

    new_version = Version(**version_data)

    try:
        session.add(new_version)
        session.commit()
    except Exception as e:
        session.rollback()
        raise e

    session.refresh(new_version)

    return responses.SuccessResponse(msg='版本创建成功', data=new_version.model_dump())


async def delete_app_version(account: Account, json_data: VersionIdJSON, session: SessionDep):
    """删除软件版本"""
    # 获取对应的应用
    app_id = json_data.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    # 获取被删除的版本
    version = session.get(Version, json_data.version_id)
    if not version or version.app_id != app_id:
        return responses.Response803()

    session.delete(version)
    session.commit()

    return responses.SuccessResponse(msg='版本已删除', data=version.model_dump(include={'id'}))


async def batch_delete_app_versions(account: Account, json_data: BatchDeleteAppVersionsJSON, session: SessionDep):
    """批量删除软件版本"""
    # 获取对应的应用
    app_id = json_data.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    versions = session.query(Version).filter(
        Version.app_id == app_id, col(Version.id).in_(json_data.version_ids)
    ).all()
    if not versions:
        return responses.SuccessResponse(msg='没有找到指定的版本', data={'count': 0, 'ids': []})

    deleted_ids = [version.id for version in versions]

    session.query(Version).filter(
        Version.app_id == app_id, col(Version.id).in_(deleted_ids)
    ).delete(synchronize_session=False)

    session.commit()

    return responses.SuccessResponse(msg='选中的版本已删除', data={
        'count': len(deleted_ids),
        'ids': deleted_ids
    })


async def clear_all_app_versions(account: Account, json_data: AppIdJSON, session: SessionDep):
    """清空所有的软件版本"""
    # 获取对应的应用
    app_id = json_data.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    # 获取该应用的所有版本
    versions = session.query(Version).filter(Version.app_id == app_id).all()
    if not versions:
        return responses.SuccessResponse(msg='该应用没有版本', data={'ids': []})

    deleted_ids = [version.id for version in versions]

    session.query(Version).filter(Version.app_id == app_id).delete(synchronize_session=False)
    session.commit()

    return responses.SuccessResponse(msg='版本已清空', data={
        'ids': deleted_ids
    })


async def update_app_version(account: Account, json_data: UpdateAppVersionJSON, session: SessionDep):
    """更新软件版本"""
    # 获取对应的应用
    app_id = json_data.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    # 获取被修改的版本
    version = session.get(Version, json_data.version_id)
    if not version or version.app_id != app_id:
        return responses.Response803()

    # 构建更新参数
    other_data = json_data.model_dump(exclude={'version_id', 'app_id'}, exclude_none=True)
    Version.sqlmodel_update(version, other_data)
    session.commit()
    session.refresh(version)

    return responses.SuccessResponse(msg='版本更新成功', data=version.model_dump())


async def publish_app_version(account: Account, json_data: PublishAppVersionJSON, session: SessionDep):
    """是否发布软件版本"""
    # 获取对应的应用
    app_id = json_data.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    # 获取被修改的版本
    version = session.get(Version, json_data.version_id)
    if not version or version.app_id != app_id:
        return responses.Response803()

    # 构建更新参数
    version.is_publish = json_data.is_publish
    session.commit()
    session.refresh(version)

    return responses.SuccessResponse(
        msg='版本已发布' if version.is_publish else '版本已下架',
        data=version.model_dump(include={'id', 'is_publish'})
    )


async def enforce_app_version(account: Account, json_data: EnforceAppVersionJSON, session: SessionDep):
    """是否指定软件版本强制更新"""
    # 获取对应的应用
    app_id = json_data.app_id
    app = session.get(App, app_id)
    if not app or app.account_id != account.aid:
        return responses.Response303()

    # 检查应用是否被超管禁用
    if app.force_disabled:
        return responses.Response304()

    # 获取被修改的版本
    version = session.get(Version, json_data.version_id)
    if not version or version.app_id != app_id:
        return responses.Response803()

    # 构建更新参数
    version.is_enforce = json_data.is_enforce
    session.commit()
    session.refresh(version)

    return responses.SuccessResponse(data=version.model_dump(include={'id', 'is_enforce'}))
